package com.jhgsys.internal.workflow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jhgsys.internal.common.utils.DateUtil;
import com.jhgsys.internal.dict.entity.Dict;
import com.jhgsys.internal.workflow.constant.WorkflowConstant;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.exception.FebsException;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.common.utils.SpringContextUtil;
import com.jhgsys.internal.system.dto.TenantDto;
import com.jhgsys.internal.system.entity.User;
import com.jhgsys.internal.system.service.IDeptService;
import com.jhgsys.internal.system.service.ITenantService;
import com.jhgsys.internal.system.service.IUserService;
import com.jhgsys.internal.workflow.dto.WorkflowApplyDto;
import com.jhgsys.internal.workflow.dto.WorkflowReviewRequestDto;
import com.jhgsys.internal.workflow.dto.WorkflowTowardDto;
import com.jhgsys.internal.workflow.entity.*;
import com.jhgsys.internal.workflow.mapper.WorkflowApplyMapper;
import com.jhgsys.internal.workflow.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 流程申请表 Service实现
 *
 * @author fenghaijun
 * @date 2024-07-19 13:53:28
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class WorkflowApplyServiceImpl extends ServiceImpl<WorkflowApplyMapper, WorkflowApply> implements IWorkflowApplyService {

    @Autowired
    private ITenantService tenantService;

    @Autowired
    private IWorkflowInfoService workflowInfoService;

    @Autowired
    private IWorkflowNodeReviewService workflowNodeReviewService;

    @Autowired
    private IWorkflowNodeService workflowNodeService;

    @Autowired
    private IWorkflowApplyReviewService workflowApplyReviewService;

    @Autowired
    private IWorkflowNodeButtonService workflowNodeButtonService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IDeptService deptService;

    @Autowired
    private IWorkflowApplyReviewLogService workflowApplyReviewLogService;

    /**
     * 查询（分页）
     * @author fenghaijun
     * @date 2024-07-19 13:53:28
     * @param request QueryRequest
     * @param workflowApply workflowApply
     * @return IPage<WorkflowApply>
    */
    @Override
    public IPage<WorkflowApply> findWorkflowApplys(QueryRequest request, WorkflowApply workflowApply) {
        LambdaQueryWrapper<WorkflowApply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WorkflowApply::getDeletedFlg, 0);
        // TODO 设置查询条件

        Page<WorkflowApply> page = new Page<>(request.getPageNum(), request.getPageSize());
        FebsUtil.pageWrapper(page, request);
        return this.page(page, queryWrapper);
    }

    /**
     * 查询（所有）
     * @author fenghaijun
     * @date 2024-07-19 13:53:28
     * @param workflowApply workflowApply
     * @return List<WorkflowApply>
     */
    @Override
    public List<WorkflowApply> findWorkflowApplys(WorkflowApply workflowApply) {
	    LambdaQueryWrapper<WorkflowApply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WorkflowApply::getDeletedFlg, FebsConstant.VALID);
		// TODO 设置查询条件
		return this.baseMapper.selectList(queryWrapper);
    }

    /**
    * 根据ID查询
    * @author fenghaijun
    * @date 2024-07-19 13:53:28
    * @param id
    * @return WorkflowApply
    */
    @Override
    public WorkflowApply findWorkflowApplyById(String id){
        return this.baseMapper.selectById(id);
    }

    /**
     * 逻辑删除
     * @author fenghaijun
     * @date 2024-07-19 13:53:28
     * @param workflowApply workflowApply
     * @param workflowApplyIds workflowApplyIds
     */
    @Override
    @Transactional
    public void deleteWorkflowApply(WorkflowApply workflowApply,String workflowApplyIds) {
        List<String> list = Arrays.asList(workflowApplyIds.split(StringPool.COMMA));
        this.baseMapper.update(workflowApply,new LambdaQueryWrapper<WorkflowApply>().in(WorkflowApply::getWorkflowApplyId,list));
	}

    /**
    * 物理删除
    * @author fenghaijun
    * @date 2024-07-19 13:53:28
    * @param workflowApplyIds workflowApplyIds
    */
    @Override
    @Transactional
    public void physicallyDeleteWorkflowApply(String workflowApplyIds) {
        List<String> list = Arrays.asList(workflowApplyIds.split(StringPool.COMMA));
        LambdaQueryWrapper<WorkflowApply> wapper = new LambdaQueryWrapper<>();
        wapper.in(WorkflowApply::getWorkflowApplyId,list);
        this.remove(wapper);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public synchronized String getWorkflowApplyNo(String tenantId) throws FebsException {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        TenantDto tenantDto = tenantService.findTenantByTenantId(tenantId);
        if(null == tenantDto || StringUtils.isBlank(tenantDto.getTenantCode())){
            throw new FebsException("流程编号生成异常");
        }
        String tenantCode = tenantDto.getTenantCode();
        LambdaQueryWrapper<WorkflowApply> queryWrapper = new LambdaQueryWrapper<WorkflowApply>();
        queryWrapper.eq(WorkflowApply::getTenantId,tenantId);
        queryWrapper.apply("DATE_FORMAT(created_time,'%Y') = DATE_FORMAT('"+ DateUtil.getDateFormat(date,"yyyy-MM-dd") +"','%Y')");
        List<WorkflowApply> workflowTaskList = this.baseMapper.selectList(queryWrapper);
        Integer length = workflowTaskList.size();
        String yearStr = String.valueOf(calendar.get(Calendar.YEAR));
        String applyNo = "AP";
        String sequencePrefix = "";
        if (length < 99999) {
            sequencePrefix = String.format("%5d", length + 1).replace(" ", "0");
        } else {
            sequencePrefix = String.format("%8d", length + 1).replace(" ", "0");
        }
        applyNo = yearStr + tenantCode + sequencePrefix;
        return applyNo;
    }

    /**
     * 保存流程申请
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveWorkflowApply(WorkflowApply workflowApply, String userName, String realNMame) throws FebsException {
        String workflowApplyId = workflowApply.getWorkflowApplyId();
        String tenantId = workflowApply.getTenantId();
        String workflowName = workflowApply.getWorkflowName();
        String workflowId = workflowApply.getWorkflowId();
        Date date = new Date();
        WorkflowInfo workflowInfo = workflowInfoService.getById(workflowId);
        if(null == workflowInfo){
            throw new FebsException("业务流程配置异常");
        }
        if("0".equals(workflowInfo.getWorkflowStatus())){
            throw new FebsException("业务流程未开启");
        }
        if (StringUtils.isNotBlank(workflowApplyId)) {
            //更新
            workflowApply.setUpdatedBy(userName);
            workflowApply.setUpdatedTime(date);
            updateById(workflowApply);
            //重置所有节点审核人员
            workflowApplyReviewService.update(
                    new LambdaUpdateWrapper<WorkflowApplyReview>().set(WorkflowApplyReview::getDeletedFlg, FebsConstant.INVALID)
                            .set(WorkflowApplyReview::getDeletedBy, userName)
                            .set(WorkflowApplyReview::getDeletedTime, date)
                            .set(WorkflowApplyReview::getReviewStatus, '0')
                            .set(WorkflowApplyReview::getTenantId, tenantId)
                            .eq(WorkflowApplyReview::getWorkflowApplyId, workflowApplyId)
            );
        } else {
            workflowApply.setTenantId(tenantId);
            workflowApply.setWorkflowName(workflowName);
            String workflowTaskNo = getWorkflowApplyNo(tenantId);
            workflowApply.setWorkflowApplyUserId(userName);
            workflowApply.setWorkflowApplyUserName(realNMame);
            workflowApply.setWorkflowApplyNo(workflowTaskNo);
            workflowApply.setCreatedBy(userName);
            workflowApply.setCreatedTime(date);
            save(workflowApply);
        }
        //#region获取流第一步程审核节点信息
        if ("2".equals(workflowApply.getWorkflowApplyStatus())) {
            WorkflowNode startNode = workflowNodeService.getStartNode(workflowId);
            if (null != startNode && WorkflowConstant.START_NODE.equals(startNode.getWorkflowNodeType())) {
                WorkflowNode nextNode = workflowNodeService.getNextNode(startNode, null,workflowApply, true);
                if (null != nextNode && null != nextNode.getWorkflowNodeId() && WorkflowConstant.APPROVE_NODE.equals(nextNode.getWorkflowNodeType())) {
                    workflowApply.setWorkflowNodeId(nextNode.getWorkflowNodeId());
                    updateById(workflowApply);
                    //根据节点获取审核人员
                    saveWorkflowReviewUser(workflowApply.getWorkflowApplyId(),nextNode,userName);
                } else {
                    throw new FebsException("流程申请提交异常：未找到流程节点");
                }
            }else{
                throw new FebsException("流程申请提交异常：未找到流程开始节点");
            }
        }
        //#endregion

        //region TODO 业务、流程通知推送

        //endregion
        return workflowApply.getWorkflowApplyId();
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean saveWorkflowReviewUser(String workflowApplyId,WorkflowNode nextNode,String createdBy){

        String tenantId = nextNode.getTenantId();
        String workflowId = nextNode.getWorkflowId();
        String workflowNodeId = nextNode.getWorkflowNodeId();
        //审批类型;1、指定人员 2、主管审批 3、指定角色 4：指定部门 5：自定义（系统集成Class返回审核人）
        String workflowNodeCheckType = nextNode.getWorkflowNodeCheckType();
        WorkflowNodeReview nodeReviewParam = new WorkflowNodeReview();
        nodeReviewParam.setTenantId(tenantId);
        nodeReviewParam.setWorkflowId(workflowId);
        nodeReviewParam.setWorkflowNodeId(workflowNodeId);
        nodeReviewParam.setWorkflowNodeCheckType(workflowNodeCheckType);
        List<WorkflowNodeReview> workflowNodeReviewList = workflowNodeReviewService.findWorkflowNodeReviews(nodeReviewParam);

        List<WorkflowApplyReview> workflowApplyReviewList = new ArrayList<>();

        switch (workflowNodeCheckType){
            case "1":
                //#region 指定人
                workflowApplyReviewList = assembleReviewByUser(workflowNodeReviewList,tenantId,workflowApplyId,workflowNodeId,createdBy);
                //endregion
                break;
            case "2":
                //#region 部门主管
                workflowApplyReviewList = assembleReviewByLeader(tenantId,workflowApplyId,workflowNodeId,createdBy);
                //#endregion
                break;
            case "3":
                //#region 指定角色
                workflowApplyReviewList = assembleReviewByRole(workflowNodeReviewList,tenantId,workflowApplyId,workflowNodeId,createdBy);
                //#endregion
                break;
            case "4":
                //#region 指定部门
                workflowApplyReviewList = assembleReviewByDept(workflowNodeReviewList,tenantId,workflowApplyId,workflowNodeId,createdBy);
                //#endregion
                break;
            case "5":
                //#region 自定义实现类
                workflowApplyReviewList = assembleReviewByCustom(workflowNodeReviewList,tenantId,workflowApplyId,workflowNodeId,createdBy);
                //#endregion
                break;
        }
        if(null != workflowApplyReviewList && workflowApplyReviewList.size() > 0 ){
            workflowApplyReviewService.saveBatch(workflowApplyReviewList);
        }
        return true;
    }


    /**
     * 工作流程审核节点：指定用户
     * @param workflowNodeReviewList
     * @param tenantId
     * @param workflowApplyId
     * @param workflowNodeId
     * @param createdBy
     * @return
     */
    private List<WorkflowApplyReview> assembleReviewByUser(List<WorkflowNodeReview> workflowNodeReviewList,String tenantId,String workflowApplyId,String workflowNodeId,String createdBy){
        WorkflowApplyReview  workflowApplyReview = new WorkflowApplyReview();
        List<WorkflowApplyReview> workflowApplyReviewList = new ArrayList<>();
        Date date = new Date();
        User userParam = new User();
        userParam.setTenantId(tenantId);
        List<User> userList = userService.findUserList(userParam);
        for (WorkflowNodeReview workflowNodeReview:workflowNodeReviewList) {
            //用户Id
            String workflowNodeCheckIds = workflowNodeReview.getWorkflowNodeCheckIds();
            User dbUser = userList.stream().filter(p -> workflowNodeCheckIds.equals(p.getUserId())).findFirst().orElse(null);
            if(null != dbUser){
                workflowApplyReview = new WorkflowApplyReview();
                workflowApplyReview.setTenantId(tenantId);
                workflowApplyReview.setWorkflowApplyId(workflowApplyId);
                workflowApplyReview.setWorkflowNodeId(workflowNodeId);
                workflowApplyReview.setReviewUserType("1");
                workflowApplyReview.setUserId(String.valueOf(dbUser.getUserId()));
                workflowApplyReview.setUserName(dbUser.getUserName());
                workflowApplyReview.setRealName(dbUser.getUname());
                workflowApplyReview.setCreatedBy(createdBy);
                workflowApplyReview.setCreatedTime(date);
                workflowApplyReviewList.add(workflowApplyReview);
            }
        }
        return  workflowApplyReviewList;
    }

    /**
     * 工作流程审核节点：部门主管
     * @param tenantId
     * @param workflowApplyId
     * @param workflowNodeId
     * @param createdBy
     * @return
     */
    private List<WorkflowApplyReview> assembleReviewByLeader(String tenantId,String workflowApplyId,String workflowNodeId,String createdBy){
        Date date = new Date();
        WorkflowApplyReview  workflowApplyReview = new WorkflowApplyReview();
        List<WorkflowApplyReview> workflowApplyReviewList = new ArrayList<>();
        User applyUser = userService.findByName(createdBy);
        String deptId = applyUser.getDeptId();

        User leaderUserParam = new User();
        leaderUserParam.setDeptLeaderFlg("1");
        leaderUserParam.setDeptId(applyUser.getDeptId());
        User leaderByDeptId = userService.findLeaderByDeptId(deptId);
        if(null != leaderByDeptId){
            workflowApplyReview = new WorkflowApplyReview();
            workflowApplyReview.setTenantId(tenantId);
            workflowApplyReview.setWorkflowApplyId(workflowApplyId);
            workflowApplyReview.setWorkflowNodeId(workflowNodeId);
            workflowApplyReview.setReviewUserType("1");
            workflowApplyReview.setUserId(leaderByDeptId.getUserId());
            workflowApplyReview.setUserName(leaderByDeptId.getUserName());
            workflowApplyReview.setCreatedBy(createdBy);
            workflowApplyReview.setCreatedTime(date);
            workflowApplyReviewList.add(workflowApplyReview);
        }
        return  workflowApplyReviewList;
    }

    /**
     * 工作流程审核节点：指定角色
     * @param workflowNodeReviewList
     * @param tenantId
     * @param workflowApplyId
     * @param workflowNodeId
     * @param createdBy
     * @return
     */
    private List<WorkflowApplyReview> assembleReviewByRole(List<WorkflowNodeReview> workflowNodeReviewList,String tenantId,String workflowApplyId,String workflowNodeId,String createdBy){
        WorkflowApplyReview  workflowApplyReview = new WorkflowApplyReview();
        List<WorkflowApplyReview> workflowApplyReviewList = new ArrayList<>();
        Date date = new Date();
        User userParam = new User();
        for (WorkflowNodeReview workflowNodeReview:workflowNodeReviewList) {
            //角色Id
            String workflowNodeCheckIds = workflowNodeReview.getWorkflowNodeCheckIds();
            List<User> dbUserList = userService.findByRoleId(workflowNodeCheckIds, tenantId);
            if(null != dbUserList && dbUserList.size()>0){
                for (User dbUser:dbUserList) {
                    workflowApplyReview = new WorkflowApplyReview();
                    workflowApplyReview.setTenantId(tenantId);
                    workflowApplyReview.setWorkflowApplyId(workflowApplyId);
                    workflowApplyReview.setWorkflowNodeId(workflowNodeId);
                    workflowApplyReview.setReviewUserType("1");
                    workflowApplyReview.setUserId(String.valueOf(dbUser.getUserId()));
                    workflowApplyReview.setUserName(dbUser.getUserName());
                    workflowApplyReview.setCreatedBy(createdBy);
                    workflowApplyReview.setCreatedTime(date);
                    workflowApplyReviewList.add(workflowApplyReview);
                }

            }
        }
        return workflowApplyReviewList;
    }


    /**
     * 工作流程审核节点：指定部门
     * @param workflowNodeReviewList
     * @param tenantId
     * @param workflowApplyId
     * @param workflowNodeId
     * @param createdBy
     * @return
     */
    private List<WorkflowApplyReview> assembleReviewByDept(List<WorkflowNodeReview> workflowNodeReviewList,String tenantId,String workflowApplyId,String workflowNodeId,String createdBy){
        WorkflowApplyReview  workflowApplyReview = new WorkflowApplyReview();
        List<WorkflowApplyReview> workflowApplyReviewList = new ArrayList<>();
        Date date = new Date();
        User userParam = new User();
        userParam.setTenantId(tenantId);
        List<User> userList = userService.findUserList(userParam);
        for (WorkflowNodeReview workflowNodeReview:workflowNodeReviewList) {
            //部门Id
            String workflowNodeCheckIds = workflowNodeReview.getWorkflowNodeCheckIds();
            User dbUser = userList.stream().filter(p -> workflowNodeCheckIds.equals(p.getDeptId())).findFirst().orElse(null);
            if(null != dbUser){
                workflowApplyReview = new WorkflowApplyReview();
                workflowApplyReview.setTenantId(tenantId);
                workflowApplyReview.setWorkflowApplyId(workflowApplyId);
                workflowApplyReview.setWorkflowNodeId(workflowNodeId);
                workflowApplyReview.setReviewUserType("1");
                workflowApplyReview.setUserId(String.valueOf(dbUser.getUserId()));
                workflowApplyReview.setUserName(dbUser.getUserName());
                workflowApplyReview.setCreatedBy(createdBy);
                workflowApplyReview.setCreatedTime(date);
                workflowApplyReviewList.add(workflowApplyReview);
            }
        }
        return workflowApplyReviewList;
    }

    /**
     * 工作流程审核节点：自定义审核权限
     * @param workflowNodeReviewList
     * @param tenantId
     * @param workflowApplyId
     * @param workflowNodeId
     * @param createdBy
     * @return
     */
    private List<WorkflowApplyReview> assembleReviewByCustom(List<WorkflowNodeReview> workflowNodeReviewList,String tenantId,String workflowApplyId,String workflowNodeId,String createdBy){
       List<WorkflowApplyReview> workflowApplyReviewList = new ArrayList<>();
       if(null != workflowNodeReviewList && workflowNodeReviewList.size() > 0 ){
           for (WorkflowNodeReview nodeReview: workflowNodeReviewList) {
               if("5".equals(nodeReview.getWorkflowNodeCheckType())){
                   //自定义实现类
                   String customClass = nodeReview.getWorkflowNodeCheckIds();
                   try {
                       Object[] args = new Object[]{workflowApplyId};
                       Class<?>[] argsType = new Class<?>[]{String.class};
                       Class<?> clazz = SpringContextUtil.getType(customClass);
                       Object instance = clazz.newInstance();
                       Method method = clazz.getMethod("execute", argsType);
                       Object result = method.invoke(instance, args);
                       //TODO 解析 result 转化为 WorkflowApplyReview

                   }catch (Exception ex){
                       log.error("工作流程审核权限自定义实现异常，自定义执行类：【"+customClass+"】,入参：【"+workflowApplyId+"】，错误信息："+ex.getMessage());
                   }
               }
           }

       }

        return workflowApplyReviewList;
    }

    /**
     * 流程审核
     * @param workflowReviewRequestDto 流程审核入参
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitWorkflowReview(WorkflowReviewRequestDto workflowReviewRequestDto) throws FebsException {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String workflowApplyId = workflowReviewRequestDto.getWorkflowApplyId();//流程申请Id
        String checkWorkflowNodeId = workflowReviewRequestDto.getCheckWorkflowNodeId();//页面流程业务审核节点Id
        String defaultReviewResult = workflowReviewRequestDto.getDefaultReviewResult();//默认按钮：审核业务操作  1：审核通过 2：审核退回 3：审核拒绝
        String customizeBtnId = workflowReviewRequestDto.getCustomizeBtnId();//自定义按钮：自定义业务按钮Id
        String beforeReviewFlg = workflowReviewRequestDto.getBeforeReviewFlg();//是否加签操作 0：未加签 1：加签
        String beforeReviewUserId = workflowReviewRequestDto.getBeforeReviewUserId();//加签审核人Id
        String userName = workflowReviewRequestDto.getUserName();//审核人账户
        String realNMame = workflowReviewRequestDto.getRealNMame();//审核人姓名

        if(StringUtils.isBlank(workflowApplyId)|| StringUtils.isBlank(checkWorkflowNodeId) || StringUtils.isBlank(userName) || StringUtils.isBlank(realNMame)){
            throw new FebsException("流程审核参数缺失，请确认");
        }
        if (StringUtils.isBlank(defaultReviewResult) && StringUtils.isBlank(customizeBtnId)){
            throw new FebsException("流程审核结果参数缺失，请确认");
        }
        if("1".equals(beforeReviewFlg) && StringUtils.isBlank(beforeReviewUserId)){
            throw new FebsException("流程加签参数缺失，请确认");
        }
        Date date = new Date();
        WorkflowApply workflowApply = findWorkflowApplyById(workflowApplyId);
        if(null == workflowApply){
           throw new FebsException("业务申请数据未找到");
        }
        String tenantId = workflowApply.getTenantId();
        String workflowId = workflowApply.getWorkflowId();
        String workflowNodeId = workflowApply.getWorkflowNodeId();
        if(!checkWorkflowNodeId.equals(workflowNodeId)){
            throw new FebsException("业务申请数据已过期，请刷新后再试");
        }
        WorkflowNode currentNode = workflowNodeService.findWorkflowNodeById(workflowNodeId);
        if(null == currentNode || !WorkflowConstant.APPROVE_NODE.equals(currentNode.getWorkflowNodeType())){
            throw new FebsException("流程节点配置异常，请联系管理员");
        }
        //是否继续业务
        boolean further = true;
        WorkflowApply WorkflowApplyUpdate = new WorkflowApply();
        WorkflowApplyUpdate.setWorkflowApplyId(workflowApplyId);
        //#region 加签：更新申请表加签标记、新增加签审核人信息
        if("1".equals(beforeReviewFlg) && further){
            User beforeReviewUser = userService.findById(beforeReviewUserId);
            if(null == beforeReviewUser || "0".equals(beforeReviewUser.getStatus())){
                throw new FebsException("流程加签审核人员信息丢失或异常");
            }
            WorkflowApplyUpdate.setNodeBeforeReviewFlg(beforeReviewFlg);
            //#加签业务
            WorkflowApplyReview applyReviewUser = new WorkflowApplyReview();
            applyReviewUser.setTenantId(workflowApply.getTenantId());
            applyReviewUser.setWorkflowApplyId(workflowApply.getWorkflowApplyId());
            applyReviewUser.setWorkflowNodeId(workflowApply.getWorkflowNodeId());
            applyReviewUser.setReviewUserType("2");
            applyReviewUser.setUserId(beforeReviewUser.getUserId());
            applyReviewUser.setUserName(beforeReviewUser.getUserName());
            applyReviewUser.setRealName(beforeReviewUser.getUname());
            applyReviewUser.setReviewStatus("0");
            applyReviewUser.setCreatedBy(userName);
            applyReviewUser.setCreatedTime(date);
            workflowApplyReviewService.save(applyReviewUser);
            further = false;
            //#endregion
        }
        //#endregion

        //#region 默认审核按钮：通过、退回、拒绝默认执行业务逻辑
        if( StringUtils.isBlank(customizeBtnId) && StringUtils.isNotBlank(defaultReviewResult) && further){
            String workflowApplyStatus = "3";
            switch (defaultReviewResult){
                case "1":
                    //#region 审核通过
                    WorkflowNode nextNode = workflowNodeService.getNextNode(currentNode, null, workflowApply, true);
                    if(null != nextNode && StringUtils.isNotBlank(nextNode.getWorkflowNodeId())){
                        WorkflowApplyUpdate.setWorkflowNodeId(nextNode.getWorkflowNodeId());
                    }else{
                        workflowApplyStatus = "6";
                    }
                    //#endregion
                    break;
                case "2":
                    //#region 审核退回
                    workflowApplyStatus = "4";
                    //#endregion
                    break;
                case "3":
                    //#region 审核拒绝
                    workflowApplyStatus = "5";
                    //#endregion
                    break;
            }
            WorkflowApplyUpdate.setWorkflowApplyStatus(workflowApplyStatus);
            WorkflowApplyUpdate.setLastWorkflowNodeId(currentNode.getWorkflowNodeId());
            WorkflowApplyUpdate.setLastWorkflowNodeName(currentNode.getWorkflowNodeName());
            WorkflowApplyUpdate.setLastWorkflowNodeReviewDate(date);
            WorkflowApplyUpdate.setUpdatedBy(userName);
            WorkflowApplyUpdate.setUpdatedTime(date);
            further = false;
        }
        //#endregion

        //#region 自定义审核按钮：根据自定义按钮配置执行业务逻辑
        if( StringUtils.isBlank(defaultReviewResult) && StringUtils.isNotBlank(customizeBtnId) && further){
            WorkflowNodeButton buttonParam = new WorkflowNodeButton();
            buttonParam.setTenantId(tenantId);
            buttonParam.setWorkflowId(workflowId);
            buttonParam.setWorkflowNodeId(workflowNodeId);
            buttonParam.setNodeButtonId(customizeBtnId);
            WorkflowNodeButton workflowNodeButton = workflowNodeButtonService.findWorkflowNodeButton(buttonParam);
            if(null == workflowNodeButton){
                throw new FebsException("业务审核操作按钮异常");
            }
            //#region 获取下一个节点 并根据条件分配审核用户
            WorkflowTowardDto workflowToward = findWorkflowToward(workflowApply, currentNode, workflowNodeButton);
            WorkflowNode nextNode = workflowToward.getNextNode();
            String workflowResultType = workflowToward.getWorkflowResultType();
            //#endregion
            further = false;
        }
        //#endregion
        updateById(WorkflowApplyUpdate);

        //#region 系统业务通知

        //#endregion

        //添加审核记录
        if(null!= workflowApply){
            WorkflowNode workflowNode = workflowNodeService.getById(workflowApply.getWorkflowNodeId());
            if(!(WorkflowConstant.NOTIFIER_NODE).equals(workflowNode.getWorkflowNodeType())){
                WorkflowApplyReviewLog workflowApplyReviewLog=new WorkflowApplyReviewLog();
                workflowApplyReviewLog.setTenantId(tenantId);
                workflowApplyReviewLog.setWorkflowApplyId(workflowApplyId);
                workflowApplyReviewLog.setWorkflowId(workflowId);
                workflowApplyReviewLog.setWorkflowNodeId(workflowApply.getWorkflowNodeId());
                workflowApplyReviewLog.setWorkflowNodeType("1");
                workflowApplyReviewLog.setReviewUserType("0".equals(workflowApply.getNodeBeforeReviewFlg())?"1":"2");
                workflowApplyReviewLog.setUserId(user.getUserId());
                workflowApplyReviewLog.setUserName(user.getUserName());
                workflowApplyReviewLog.setRealName(user.getUname());
                workflowApplyReviewLog.setReviewResult(defaultReviewResult);
                workflowApplyReviewLog.setReviewRemark(workflowReviewRequestDto.getReviewRemark());
                workflowApplyReviewLog.setReviewDate(new Date());
                workflowApplyReviewLog.setReadable("0");
                workflowApplyReviewLog.setCreatedBy(user.getUserName());
                workflowApplyReviewLog.setCreatedTime(new Date());
                workflowApplyReviewLog.setDeletedFlg("0");
                workflowApplyReviewLogService.save(workflowApplyReviewLog);
            }
        }

        return true;
    }

    /**
     * 根据流程节点按钮配置判断流程走向
     * @param currentNode
     * @param workflowNodeButton
     */
    private WorkflowTowardDto findWorkflowToward(WorkflowApply workflowApply, WorkflowNode currentNode, WorkflowNodeButton workflowNodeButton) throws FebsException {
        String workflowResultType = "";
        Date date = new Date();
        WorkflowTowardDto workflowTowardDto = new WorkflowTowardDto();
        WorkflowNode nextNode = new WorkflowNode();
        WorkflowApply WorkflowApplyUpdate = new WorkflowApply();
        WorkflowApplyUpdate.setWorkflowApplyId(workflowApply.getWorkflowApplyId());
        //按钮类型;1：通过按钮 2：退回按钮 3：拒绝按钮 4：自定义按钮
        String nodeButtonType = workflowNodeButton.getNodeButtonType();
        //是否默认事件 0：否 1：是
        String defaultEvent = workflowNodeButton.getDefaultEvent();
        //自定义事件
        String customEvent = workflowNodeButton.getCustomEvent();
        //流转方式;1：下一节点 2：上一节点 3：指定节点
        String transferWay = workflowNodeButton.getTransferWay();
        //指定流程节点Id
        String transferNodeId = workflowNodeButton.getTransferNodeId();
        if("1".equals(defaultEvent) && "4".equals(nodeButtonType)){
            //自定义节点出现默认事件：配置异常
            throw new FebsException("自定义按钮属性配置异常");
        }
        if("1".equals(defaultEvent)){
            //region默认按钮事件
            switch (nodeButtonType){
                case "1":
                    //#region 通过按钮:下一节点
                    nextNode = workflowNodeService.getNextNode(currentNode, workflowNodeButton.getNodeButtonId(), workflowApply, true);
                    workflowResultType = "1";
                    //#endregion
                    break;
                case "2":
                    //#region 退回按钮：业务表重置为待审核之前状态，流程申请表状态：已退回
                    workflowResultType = "2";
                    //#endregion
                    break;
                case "3":
                    //#region 拒绝按钮：业务表重置为已拒绝，流程申请表状态：已拒绝
                    workflowResultType = "3";
                    //#endregion
                    break;
            }
            //#endregion
        }else{
            //#region自定义流转
            switch (transferWay){
                case "1":
                    //#region下一节点
                    nextNode = workflowNodeService.getNextNode(currentNode, workflowNodeButton.getNodeButtonId(), workflowApply, true);
                    //#endregion
                    break;
                case "2":
                    //#region 上一节点
                    //TODO
                    //#endregion
                    break;
                case "3":
                    //#region 指定节点
                    nextNode = workflowNodeService.findWorkflowNodeById(transferNodeId);
                    //#endregion
                    break;
            }
            workflowResultType = "1";
            //#endregion
        }
        if( "1".equals(workflowResultType) && ( null == nextNode || StringUtils.isBlank(nextNode.getWorkflowNodeId()) || !WorkflowConstant.APPROVE_NODE.equals(nextNode.getWorkflowNodeType()) || !nextNode.getTenantId().equals(workflowApply.getTenantId()))){
            throw new FebsException("流程扭转异常，请联系管理员");
        }
        workflowTowardDto.setNextNode(nextNode);
        workflowTowardDto.setWorkflowResultType(workflowResultType);
        return workflowTowardDto;
    }

    /**
     * 查询（分页）
     * @author fenghaijun
     * @date 2024-07-19 13:53:28
     * @param request QueryRequest
     * @param workflowApply workflowApply
     * @return IPage<WorkflowApply>
     */
    @Override
    public IPage<WorkflowApplyDto> findApplyAndPeccancy(QueryRequest request, WorkflowApplyDto workflowApply) {
        Page<WorkflowApplyDto> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<WorkflowApplyDto> applyAndPeccancy = this.baseMapper.findApplyAndPeccancy(page, workflowApply);
        return applyAndPeccancy;
    }

}
